package model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import utils.ScoredEntities;

import edu.stanford.nlp.ling.TaggedWord;

public class Sentence extends ArrayList<TaggedWord> {

	public Sentence(ArrayList<TaggedWord> tokens) {
		this.addAll(tokens);
	}

	/**
	 * Just sums up the scores of the terms in the sentence, according to the
	 * dictionary
	 * 
	 * @param v
	 *            the dictionary keeping the mapping of entities and scores
	 * @param longTermFirst
	 *            whether or not to match long terms first. useful if intending
	 *            to match phrases
	 * @return the sum of scores of the matched terms in the sentence
	 */
	public double scoreSum(ScoredEntities v, boolean longTermFirst) {
		double score = 0;
		if (longTermFirst) {
			StringBuilder line = new StringBuilder("");
			List<String> sortedWords = v.sortByLength();
			for (TaggedWord word : this) {
				line.append(word.word().toLowerCase() + " ");
			}
			for (String entity : sortedWords) {
				int start = 0;
				while ((start = line.indexOf(" " + entity + " ")) != -1) {
					score += Math.abs(v.getScore(entity));
					line.delete(start + 1, start + entity.length() + 1);
				}
			}
		} else {
			for (TaggedWord word : this) {
				Double wordScore = v.get(word.word());
				if (wordScore != null) {
					score += wordScore;
				}
			}
		}
		return score;
	}

	/**
	 * Sum up the scores of the matched terms in the sentence, according to the
	 * dictionary, and then normalize by the length of the sentence
	 * 
	 * @param v
	 *            the dictionary keeping the mapping of entities and scores
	 * @param longTermFirst
	 *            whether or not to match long terms first. useful if intending
	 *            to match phrases
	 * @return the normalized score of the sentence
	 */
	public double scoreNormalized(HashMap<String, Double> vocabulary,
			boolean longTermFirst) {
		double score = 0;
		for (TaggedWord word : this) {
			Double wordScore = vocabulary.get(word.word());
			if (wordScore != null) {
				score += wordScore * wordScore;
			}
		}
		return score / (this.size());
	}

	/**
	 * String representation
	 */
	public String toString(boolean keepTags) {
		String sentence = "";
		for (TaggedWord word : this) {
			if (keepTags) {
				sentence = sentence
						.concat(word.word() + "/" + word.tag() + ' ');
			} else {
				sentence = sentence.concat(word.word() + ' ');
			}
		}
		return sentence;
	}

}
